module Engine where

type Change a = a -> Maybe a

data Pos = Line Int | Begin | End Int

distance (Line n) (Line m) 	= m - n +1
distance (Line m) Begin 	= m
distance (End m)  (Line n) 	= m - n
distance (End m)  Begin		= m
distance _ _ 			= 0	 

class Engine a where
	empty 		:: ( a)
	empty 		= listIn []
	listIn		:: [String] -> a
	listOut 	:: a -> Maybe [String]
	values		:: Int -> a -> Maybe [String]
	line 		:: a -> Maybe String
	line w 		= head `fmap` values 1 w 
	jump 		:: Int -> Change a
	ins		:: [String] -> Change a
	add		:: [String] -> Change a
	del 		:: Change a
	deln 		:: Int -> Change a
	end 		:: Change a 
	start		:: Change a
	pos		:: a -> Pos
	next		:: Change a
	prev 		:: Change a 
	prevn 		:: Int -> Change a
	prevn 0 w	= Just w
	prevn n w 	= prev w >>= prevn (n-1) 
	nextn 		:: Int -> Change a
	nextn 0 w	= Just w
	nextn n w 	= next w >>= nextn (n-1) 
	rjump		:: Int -> Change a
	rjump n		= iterateM n (if n > 0 then next else prev) where
		iterateM n f w 	| n > 0 = f w >>= iterateM (n - 1) f
				| True = Just w


